package server

import (
	"encoding/json"
	"fmt"
	"mcp-clarification-service/internal/config"
	"mcp-clarification-service/internal/protocol"
	"mcp-clarification-service/internal/tools"
	"mcp-clarification-service/internal/transport"
	"mcp-clarification-service/pkg/logger"
	"time"
)

// MCPServer MCP服务器
type MCPServer struct {
	transport    *transport.StdioTransport
	handler      *tools.Handler
	dispatcher   *tools.Dispatcher
	config       *config.Config
	logger       *logger.Logger
	initialized  bool
	capabilities protocol.ServerCapabilities
}

// NewMCPServer 创建新的MCP服务器
func NewMCPServer(cfg *config.Config, log *logger.Logger) *MCPServer {
	httpClient := tools.NewHTTPClient(cfg.GUIService.URL, time.Duration(cfg.Defaults.Timeout)*time.Second)
	dispatcher := tools.NewDispatcher(100, httpClient, cfg.Defaults.Timeout)
	registry := tools.NewRegistry()
	handler := tools.NewHandler(registry, dispatcher, time.Duration(cfg.Defaults.Timeout)*time.Second)

	return &MCPServer{
		transport:  transport.NewStdioTransport(),
		handler:    handler,
		dispatcher: dispatcher,
		config:     cfg,
		logger:     log,
		capabilities: protocol.ServerCapabilities{
			Tools: protocol.ToolsCapability{
				ListChanged: false,
			},
		},
	}
}

// Start 启动服务器
func (s *MCPServer) Start() error {
	s.logger.Info("Starting MCP server...")

	// 检查并启动 GUI 服务（阻塞直到就绪）
	if s.config.GUIService.AutoStart {
		if err := s.ensureGUIServiceRunning(); err != nil {
			s.logger.Error("Failed to start GUI service: %v", err)
			s.logger.Error("MCP server cannot start without GUI service")
			return fmt.Errorf("GUI service startup failed: %w", err)
		}
		s.logger.Info("GUI service is ready")
	}

	// 启动调度器
	s.dispatcher.Start()
	defer s.dispatcher.Stop()

	// 服务器已准备好，输出就绪消息
	s.logger.Info("MCP server is ready and waiting for requests")

	// 主循环
	for {
		// 读取消息
		data, err := s.transport.ReadMessage()
		if err != nil {
			s.logger.Error("Failed to read message: %v", err)
			return err
		}

		// 解析消息
		msg, err := protocol.Unmarshal(data)
		if err != nil {
			s.logger.Error("Failed to unmarshal message: %v", err)
			s.sendError(nil, protocol.ParseError, "Parse error", nil)
			continue
		}

		// 处理消息
		if err := s.handleMessage(msg); err != nil {
			s.logger.Error("Failed to handle message: %v", err)
		}
	}
}

// handleMessage 处理消息
func (s *MCPServer) handleMessage(msg *protocol.JSONRPCMessage) error {
	if msg.IsRequest() {
		return s.handleRequest(msg)
	} else if msg.IsNotification() {
		return s.handleNotification(msg)
	}
	return fmt.Errorf("unexpected message type")
}

// handleRequest 处理请求
func (s *MCPServer) handleRequest(msg *protocol.JSONRPCMessage) error {
	switch msg.Method {
	case "initialize":
		return s.handleInitialize(msg)
	case "tools/list":
		return s.handleToolsList(msg)
	case "tools/call":
		return s.handleToolsCall(msg)
	default:
		return s.sendError(msg.ID, protocol.MethodNotFound, "Method not found", nil)
	}
}

// handleNotification 处理通知
func (s *MCPServer) handleNotification(msg *protocol.JSONRPCMessage) error {
	switch msg.Method {
	case "notifications/initialized":
		s.logger.Info("Client initialized")
		return nil
	default:
		s.logger.Warn("Unknown notification: %s", msg.Method)
		return nil
	}
}

// handleInitialize 处理初始化
func (s *MCPServer) handleInitialize(msg *protocol.JSONRPCMessage) error {
	var params protocol.InitializeParams
	if err := json.Unmarshal(msg.Params, &params); err != nil {
		return s.sendError(msg.ID, protocol.InvalidParams, "Invalid params", nil)
	}

	result := protocol.InitializeResult{
		ProtocolVersion: "2024-11-05",
		Capabilities:    s.capabilities,
		ServerInfo: protocol.ServerInfo{
			Name:    s.config.Server.Name,
			Version: s.config.Server.Version,
		},
	}

	s.initialized = true
	s.logger.Info("Initialized with client: %s %s", params.ClientInfo.Name, params.ClientInfo.Version)

	return s.sendResponse(msg.ID, result)
}

// handleToolsList 处理工具列表请求
func (s *MCPServer) handleToolsList(msg *protocol.JSONRPCMessage) error {
	if !s.initialized {
		return s.sendError(msg.ID, protocol.InvalidRequest, "Not initialized", nil)
	}

	result := protocol.ToolsListResult{
		Tools: s.handler.ListTools(),
	}

	return s.sendResponse(msg.ID, result)
}

// handleToolsCall 处理工具调用
func (s *MCPServer) handleToolsCall(msg *protocol.JSONRPCMessage) error {
	if !s.initialized {
		return s.sendError(msg.ID, protocol.InvalidRequest, "Not initialized", nil)
	}

	var params protocol.ToolCallParams
	if err := json.Unmarshal(msg.Params, &params); err != nil {
		return s.sendError(msg.ID, protocol.InvalidParams, "Invalid params", nil)
	}

	s.logger.Info("Calling tool: %s", params.Name)

	result, err := s.handler.HandleToolCall(params.Name, params.Arguments)
	if err != nil {
		s.logger.Error("Tool call failed: %v", err)
		return s.sendError(msg.ID, protocol.InternalError, err.Error(), nil)
	}

	return s.sendResponse(msg.ID, result)
}

// sendResponse 发送响应
func (s *MCPServer) sendResponse(id interface{}, result interface{}) error {
	resp, err := protocol.NewResponse(id, result)
	if err != nil {
		return err
	}

	data, err := resp.Marshal()
	if err != nil {
		return err
	}

	return s.transport.WriteMessage(data)
}

// sendError 发送错误响应
func (s *MCPServer) sendError(id interface{}, code int, message string, data interface{}) error {
	resp := protocol.NewErrorResponse(id, code, message, data)
	respData, err := resp.Marshal()
	if err != nil {
		return err
	}

	return s.transport.WriteMessage(respData)
}

// ensureGUIServiceRunning 确保 GUI 服务正在运行
func (s *MCPServer) ensureGUIServiceRunning() error {
	// 检查 GUI 服务是否已经运行
	if s.isGUIServiceRunning() {
		s.logger.Info("GUI service is already running")
		return nil
	}

	s.logger.Info("GUI service not running, attempting to start...")

	// 尝试启动 GUI 服务
	if err := s.startGUIService(); err != nil {
		return err
	}

	// 等待 GUI 服务变为可用，最多等待 10 秒（增加等待时间）
	healthClient := tools.NewHTTPClient(s.config.GUIService.URL, 500*time.Millisecond)
	deadline := time.Now().Add(10 * time.Second)

	for time.Now().Before(deadline) {
		if ok, _ := healthClient.HealthCheck(); ok {
			s.logger.Info("GUI service started successfully")
			// 额外等待 500ms 确保服务完全就绪
			time.Sleep(500 * time.Millisecond)
			return nil
		}
		time.Sleep(200 * time.Millisecond)
	}

	return fmt.Errorf("GUI service did not become ready within 10 seconds")
}

// isGUIServiceRunning 检查 GUI 服务是否运行
func (s *MCPServer) isGUIServiceRunning() bool {
	client := tools.NewHTTPClient(s.config.GUIService.URL, 500*time.Millisecond)
	ok, _ := client.HealthCheck()
	return ok
}

// startGUIService 启动 GUI 服务
func (s *MCPServer) startGUIService() error {
	// 导入需要的包
	return startGUIServiceProcess(s.logger)
}
